home *** CD-ROM | disk | FTP | other *** search
- /*
- * token.c : piddle with tokens
- */
-
- /* Copyright 1990, 1991, 1992 Craig Durland
- * Distributed under the terms of the GNU General Public License.
- * Distributed "as is", without warranties of any kind, but comments,
- * suggestions and bug reports are welcome.
- */
-
- #include <stdio.h>
- #include <os.h>
- #include <const.h>
- #include <dtable.h>
- #include "mc.h"
- #include "mm.h"
- #include "opcode.h"
-
- extern char ebuf[], *malloc(), *savestr(), *spoof();
-
- /***********************************************************************
- ********************* Token tables *************************************
- ***********************************************************************/
-
- MuttCmd
- /* holes: 22, 30, 32-41, 44-59, 74 */
- muttcmds[] = /* biggest # = 81 */
- {
- "!=", 0,
- "*", 65,
- "*=", 66,
- "+", 3,
- "+=", 63,
- "-", 67,
- "-=", 68,
- "/", 69,
- "/=", 70,
- "<", 11,
- "<=", 10,
- "==", 12,
- ">", 13,
- ">=", 14,
- "and", 80,
- "arg", 43,
- "array", 73,
- "ask-user", 26,
- "bool", 62,
- "break", 7,
- "byte", 75,
- "cond", 1,
- "const", 77,
- "continue", 71,
- "convert-to", 20,
- "defun", 2,
- "done", 9,
- "extract-element", 24,
- "extract-elements", 25,
- "floc", 78,
- "for", 76,
- "goto", 6,
- "halt", 16,
- "if", 23,
- "include", 64,
- "insert-object", 18,
- "int", 31,
- "label", 8,
- "length-of", 19,
- "list", 27,
- "loc", 79,
- "nargs", 42,
- "not", 28,
- "novalue", 29,
- "or", 81,
- "pointer", 72,
- "push-arg", 17,
- "push-args", 15,
- "remove-elements", 21,
- "small-int", 61,
- "string", 60,
- "switch", 4,
- "while", 5,
- },
- modifiers[] = /* the pgm modifiers */
- {
- "HIDDEN", HIDDEN,
- "MAIN", MAIN,
- };
-
- oMuttCmd
- omuttcmds[] = /* the other Mutt commands, see other_Mutt_cmd() */
- {
- "ask", ASK, STRING,
- "concat", CONCAT, STRING,
- "extract-element", EXTRACT_EL, UNKNOWN,
- "extract-elements", EXTRACT_ELS,UNKNOWN, /* !!!actually, same as first arg */
- "insert-object", INSERT_OBJ, UNKNOWN,
- "msg", MSG, STRING,
- "remove-elements", REMOVE_ELS, VOID,
- };
-
- int
- msize = NITEMS(muttcmds),
- omsize = NITEMS(omuttcmds), moders = NITEMS(modifiers);
-
-
- /* ******************************************************************** */
- /* ************************* External Tokens ************************** */
- /* ******************************************************************** */
-
- /*
- * A token table is stored in a file.
- * Format:
- * <token number> <token name>
- */
-
- static declare_and_init_dTable(ext_token_table,MuttCmd);
- static int num_ext_tokens = 0;
-
- void load_ext_token_table(fname) char *fname;
- {
- char buf[90], *ptr;
- int t;
- FILE *fptr;
-
- new_ext(buf,fname,".tok");
- if ((fptr = fopen(buf,"r")) == NULL)
- bitch(spoof(ebuf,"Can't open token file %s!",buf));
-
- while ((ptr = fgets(buf,80,fptr)))
- {
- if (!xpand_dTable(&ext_token_table, 1, 100,50))
- {
- printf("Out of memory! Can't expand external token table.\n");
- exit(1);
- }
- buf[strlen(buf)-1] = '\0';
- t = atoi(ptr); while (*ptr++!=' ') ;
- if (NULL == (ptr = savestr(ptr)))
- bail("Can't malloc external token name");
-
- ext_token_table.table[num_ext_tokens].name = ptr;
- ext_token_table.table[num_ext_tokens].token = t;
- num_ext_tokens++;
- }
- }
-
- /* Look for an external token by name. Returns value.
- * Input:
- * name: name of the token to search for. If NULL, search by value.
- * Returns:
- * -1 : name not found.
- * val : token value.
- */
- lookup_ext_token_by_name(name) char *name;
- {
- return lookup(name, ext_token_table.table, num_ext_tokens);
- }
-
- /* Look for an external token by value. Returns name.
- * Input:
- * val: token value to search for if name is NULL.
- * Returns:
- * NULL : val not found
- * pointer to the token name
- */
- char *lookup_ext_token_by_value(val)
- {
- int j;
-
- for (j = 0; j < num_ext_tokens; j++)
- if (ext_token_table.table[j].token == val)
- return ext_token_table.table[j].name;
-
- return NULL;
- }
-
-
- /* ******************************************************************** */
- /* ******************* Mutt Table Look Up Routines ******************** */
- /* ******************************************************************** */
-
- /* Use binary search table to find name
- * returns: token (if name in table) else -1
- */
- /* ??? use bsearch */
- lookup(name,table,n) char *name; MuttCmd *table;
- {
- register int j, lower = 0, upper = n-1, x;
-
- while (lower <= upper)
- {
- j = (lower+upper)/2;
- if ((x = strcmp(name,table[j].name))>0) lower = j +1;
- else if (x<0) upper = j -1; else return table[j].token;
- }
- return -1;
- }
-
- /* ??? use bsearch */
- oMuttCmd *olookup(name,table,n) char *name; oMuttCmd *table;
- {
- register int j, lower = 0, upper = n-1, x;
-
- while (lower<=upper)
- {
- j = (lower+upper)/2;
- if ((x = strcmp(name,table[j].name))>0) lower = j +1;
- else if (x<0) upper = j -1; else return &table[j];
- }
- return NULL;
- }
-
- /***********************************************************************
- ********************* Conversion routines ******************************
- ***********************************************************************/
-
- int32 atoN(a) char *a; /* convert string to NUMBER */
- {
- char c, *b=a;
- int minus = FALSE, base = 10, z;
- int32 n = 0;
-
- if (*a == '-') { a++; minus = TRUE; }
- if (*a == '0' && a[1] == 'x') { base = 16; a += 2; }
- for (; *a; a++)
- {
- c = *a; z = 1000;
- if ('0' <= c && c <= '9') z = c -'0';
- else
- if ('a' <= c && c <= 'f') z = c -'a' +10;
- else if ('A' <= c && c <= 'F') z = c -'A' +10;
- if (z >= base) { moan(spoof(ebuf,"Invalid digit in %s",b)); break; }
- n = n*base +z;
- }
- return minus ? -n : n;
- }
-
- /***********************************************************************
- ********************* Scanning routines ********************************
- ***********************************************************************/
-
- #include <ctype.h>
-
- extern char token[]; /* in mc.c */
- extern FILE *lstfile, *srcfile; /* in mc.c */
- extern int srcline; /* in mc.c */
- extern unsigned int class;
-
- static char pgmtext[514], *xptr;
- static int looked = FALSE;
- static unsigned int proclass;
-
- int btv = FALSE; /* boolean token value - returned by get_token() */
-
- /* move the pc to the next nonwhite character
- * returns: TRUE if ok, FALSE if EoF
- */
- getsrc()
- {
- char *ptr;
-
- if ((xptr = fgets(pgmtext,512,srcfile)) == NULL) return FALSE;
- if (*(ptr = xptr + strlen(xptr) -1) == '\n') *ptr = '\0';
- srcline++;
- if (lstfile) fprintf(lstfile,"LINE %d: %s\n",srcline,xptr);
- return TRUE;
- }
-
- /* skip comment => skip to next line */
- /* EoF: Ok if comment is last thing in buffer/file */
- #define nocomment() getsrc()
-
- static scan()
- {
- top: /* incase got to get a new line */
- while (isspace(*xptr)) xptr++; /* delete leading white space */
- if (*xptr == '\0' || *xptr == '\n')
- if (getsrc()) goto top; else return FALSE;
- if (*xptr == ';') if (nocomment()) goto top; else return FALSE;
- return TRUE;
- }
-
- /* returns: TRUE (all ok), FALSE (something screwed up)
- */
- void get_token()
- {
- register char *ptr;
-
- if (looked) { looked = FALSE; class = proclass; return; }
-
- *(ptr = token) = '\0'; class = TOKEN;
- if (!scan()) { class = proclass = SEOF; return; }
- switch (*xptr)
- {
- case '\'': /* string literal: 'string', ''=>' */
- for (xptr++; *xptr && ptr < (token +250); xptr++)
- if (*xptr == '\'' && *++xptr != '\'') goto uggg;
- else *ptr++ = *xptr;
- if (*xptr == '\0') bitch("String not terminated!");
- uggg:
- class = STRING;
- break;
- case '\"': /* "string": knows about \ (quote), ^ (control) */
- for (xptr++; *xptr && *xptr != '\"' && ptr < (token +250); xptr++)
- switch (*xptr)
- {
- case '\\': *ptr++ = *++xptr; break; /* \ : quote next char */
- case '^': *ptr++ = *++xptr ^ 0x40; break; /* ^ => cntl char */
- default: *ptr++ = *xptr;
- }
- if (*xptr == '\0') bitch("String not terminated!");
- xptr++; class = STRING;
- break;
- default: /* get a token or number */
- while (*xptr && !isspace(*xptr))
- {
- if (strchr("(){};",*xptr))
- {
- if (ptr == token) { class = DELIMITER; *ptr++ = *xptr++; }
- break;
- }
- *ptr++ = *xptr++;
- }
- }
- *ptr = '\0';
- if (class == TOKEN)
- {
- if ((isdigit(*token) || (*token == '-' && isdigit(*(token+1)))))
- class = NUMBER;
- else if (strcmp(token,"FALSE") == 0) { class = BOOLEAN; btv = FALSE; }
- else if (strcmp(token,"TRUE") == 0) { class = BOOLEAN; btv = TRUE; }
- }
- proclass = class;
- return;
- }
-
- /* Note: gotta be careful class don't get trashed between
- * lookahead() & get_token()
- */
- void lookahead()
- {
- if (looked) { class = proclass; return; }
- get_token(); looked = TRUE;
- }
-
- typedef struct Inca { struct Inca *next; char fname[1]; } Inca;
- static Inca *inchead = NULL;
-
- include(fname) char *fname;
- {
- register Inca *ptr;
-
- for (ptr = inchead; ptr; ptr = ptr->next)
- if (strcmp(ptr->fname,fname) == 0)
- {
- gripe(spoof(ebuf,"Already included: %s. Ignoring.",fname));
- nocomment(); /* bloto rest of line */
- return UNKNOWN;
- }
- if (NULL == (ptr = (Inca *)malloc(sizeof(Inca) +strlen(fname))))
- bail("Out of memory in include()");
- strcpy(ptr->fname,fname);
- ptr->next = inchead; inchead = ptr;
- pilefile(fname,TRUE);
- getsrc(); /* prime scan() */
-
- return UNKNOWN;
- }
-